#ifndef CORE_H
#define CORE_H

#ifndef AE_MAKEFILE
#if defined(_WIN32) || defined(_WIN64)
#define AE_WIN32
#elif defined(linux) || defined(__linux__)
#define AE_LINUX
#elif defined(__FreeBSD__)
#define AE_FREEBSD
#else
#error "Unsupported platform for compile AE"
#endif
#endif

#if defined(AE_WIN32)
#define WINVER 0x0501
#define _WIN32_WINNT 0x0501
#define WIN32_LEAN_AND_MEAN
#include <winsock2.h>
#include <ws2tcpip.h>
#include <mswsock.h>
#include <windows.h>
#if defined(_MSC_VER)
#pragma comment(lib,"ws2_32")
#pragma comment(lib,"mswsock")
#endif
#else
#define AE_POSIX
#include <sys/types.h>
#include <sys/time.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <errno.h>
#include <unistd.h>
#include <pthread.h>
#if defined(AE_LINUX)
#include <sys/epoll.h>
#elif defined(AE_FREEBSD)
#include <sys/event.h>
#endif
#endif

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "ae.h"
#include "list.h"
#include "rbtree.h"
#include "mutex.h"
#include "atomic.h"

#define AE_MIN(X,Y) ((X) < (Y) ? (X) : (Y))
#define AE_MAX(X,Y) ((X) < (Y) ? (X) : (Y))

static inline void* ae_malloc(size_t size)
{
	return malloc(size);
}

static inline void* ae_mallocz(size_t size)
{
	return calloc(1, size);
}

static inline void ae_free(void* memblock)
{
	free(memblock);
}

enum object_type {
	OBJ_NULL,
	OBJ_EVENT,
	OBJ_CAN_EVENT = 0x80000000,
	OBJ_SOCKET,
};

struct object_base {
	enum object_type type;
};

#define INHERIT_OBJECT				\
	struct object_base __object

#define TO_OBJECT(o)				\
	((struct object_base*)o)

#define SET_OBJECT_TYPE(o, t)			\
	TO_OBJECT((o))->type = t

#define GET_OBJECT_TYPE(o)			\
	TO_OBJECT((o))->type

#define CHECK_OBJECT(o, t)				\
	(((o) != NULL) && (GET_OBJECT_TYPE(o) == t))

#define CHECK_OBJECT_CANEVENT(o)				\
	(((o) != NULL) && (GET_OBJECT_TYPE(o) > OBJ_CAN_EVENT))

#endif
